/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.mysql.injector.method;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.mysql.injector.enums.MySqlMethod;
import java.util.List;
import java.util.function.Predicate;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

/**
 * 批量替换数据,自选字段 replace into
 */
public class ReplaceIntoBatchSomeColumn extends AbstractMethod {

  /**
   * 字段筛选条件
   */
  private final Predicate<TableFieldInfo> predicate;

  public ReplaceIntoBatchSomeColumn(Predicate<TableFieldInfo> predicate) {
    super(MySqlMethod.REPLACE_INTO_BATCH_SOME_COLUMN.getMethod());
    this.predicate = predicate;
  }

  @SuppressWarnings("Duplicates")
  @Override
  public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    KeyGenerator keyGenerator = new NoKeyGenerator();
    MySqlMethod sqlMethod = MySqlMethod.REPLACE_INTO_BATCH_SOME_COLUMN;
    List<TableFieldInfo> fieldList = tableInfo.getFieldList();
    String insertSqlColumn =
      tableInfo.getKeyInsertSqlColumn(true, false) + this.filterTableFieldInfo(fieldList, predicate,
        TableFieldInfo::getInsertSqlColumn, EMPTY);
    String columnScript = LEFT_BRACKET + insertSqlColumn.substring(0, insertSqlColumn.length() - 1) + RIGHT_BRACKET;
    String insertSqlProperty =
      tableInfo.getKeyInsertSqlProperty(true, ENTITY_DOT, false) + this.filterTableFieldInfo(fieldList, predicate,
        i -> i.getInsertSqlProperty(ENTITY_DOT), EMPTY);
    insertSqlProperty = LEFT_BRACKET + insertSqlProperty.substring(0, insertSqlProperty.length() - 1) + RIGHT_BRACKET;
    String valuesScript = SqlScriptUtils.convertForeach(insertSqlProperty, Constants.COLL, null, ENTITY, COMMA);
    String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
    return this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource, keyGenerator, null,
      null);
  }

}
